﻿using BaoShouTangServer.DTOModel;
using BaoShouTangServer.Models;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Web;
using System.Xml;

namespace BaoShouTangServer.Service
{
    public static class U8Service
    {
        private static readonly NLog.Logger Logger = NLog.LogManager.GetCurrentClassLogger();
        public static List<DTOU8材料出库单导入结果> 生成U8材料出库单(long paigongId,string beiLiaoName)
        {
            List<DTOU8材料出库单导入结果> 导入结果List = new List<DTOU8材料出库单导入结果>();
            string 需要出库的仓库 = ConfigurationManager.AppSettings["cWhCode"].ToString();
            string[] 仓库 = 需要出库的仓库.Split(',');
            //查询派工记录的订单信息
            Z_派工 z_派工 = SqlSugarHelp.scope.Queryable<Z_派工>().Where(it => it.id == paigongId).IgnoreColumns(it => it.工票二维码).First();


            //查询订单子件，且不在半成品仓
            List<DTOBOMDetail> dTOBOMDetailList = SqlSugarHelp.scope.Queryable<mom_order, mom_orderdetail, mom_moallocate, Inventory>((morder, orderdetail, moallocate, inv) => new JoinQueryInfos(
                                                                             JoinType.Left, morder.MoId == orderdetail.MoId,
                                                                             JoinType.Left, orderdetail.MoDId == moallocate.MoDId,
                                                                             JoinType.Left, inv.cInvCode == moallocate.InvCode
                                                                             )).Where((morder, orderdetail, moallocate, inv) => 
                                                                             !仓库.Contains(moallocate.WhCode) && morder.MoCode == z_派工.订单号 && orderdetail.SortSeq == z_派工.订单行号)
                                                                             .Select((morder, orderdetail, moallocate, inv) =>
                                                                             new DTOBOMDetail
                                                                             {
                                                                                 生产订单ID = morder.MoId,
                                                                                 生产订单号 = morder.MoCode,
                                                                                 生产订单行ID = orderdetail.MoDId,
                                                                                 生产订单行号 = orderdetail.SortSeq,
                                                                                 产品编号 = orderdetail.InvCode,
                                                                                 生产令单的所有子件用料资料ID = moallocate.AllocateId,
                                                                                 子件行号 = moallocate.SortSeq,
                                                                                 子件物料编号 = moallocate.InvCode,
                                                                                 子件物料名称 = inv.cInvName,
                                                                                 工序行号 = moallocate.OpSeq,
                                                                                 基本用量分子 = moallocate.BaseQtyN,
                                                                                 基本用量分母 = moallocate.BaseQtyD,
                                                                                 仓库编号 = moallocate.WhCode
                                                                             })
                                                                             .ToList();
            Logger.Warn("备料接口，查询子件的数量"+ dTOBOMDetailList.Count);

            if (dTOBOMDetailList != null && dTOBOMDetailList.Count > 0)
            {
                //根据仓库分组，因为材料出库单表头有材料仓库必填项
                var dtoBOMDetailGroup = dTOBOMDetailList.GroupBy(it => it.仓库编号);
                foreach (var item in dtoBOMDetailGroup)
                {
                    DTOU8材料出库单导入结果 导入结果 = new DTOU8材料出库单导入结果();
                    string 出库单号 = Get出库单号(DateTime.Today.ToString("yyyy-MM-dd"));
                  string result =  U8出库单Port(出库单号, z_派工.订单号, z_派工.id.ToString(), item.Key, item.ToList(), z_派工.派工数量.GetValueOrDefault(), beiLiaoName,z_派工.cUser_Name);
                    int r = 0;
                    // 查出材料出库单号
                    rdrecord11 rdrecord11 = SqlSugarHelp.scope.Queryable<rdrecord11>().Where(it => it.cCode == 出库单号).First();
                    if (rdrecord11 != null)
                    {
                       r = 更新材料已领数量(item.ToList(), z_派工.订单号, z_派工.订单行号.ToString(), 0, 出库单号, rdrecord11, z_派工.产品编号);
                        //写入备料备注
                        List<Z_BeiLiaoMemo> Z_BeiLiaoMemoList = new List<Z_BeiLiaoMemo>();
                        foreach (var beiliao in item.ToList())
                        {
                            Z_BeiLiaoMemo memo = new Z_BeiLiaoMemo();
                            memo.备料出库结果 = result;
                            memo.订单行号 = beiliao.生产订单行号;
                            memo.子件行号 = beiliao.子件行号;
                            memo.派工单号 = paigongId;
                            Z_BeiLiaoMemoList.Add(memo);
                            
                        }
                        var x = SqlSugarHelp.scope.Storageable(Z_BeiLiaoMemoList)
                                    .WhereColumns(it => new { it.派工单号, it.子件行号, it.订单行号 })//当然支持多个 new {it.id,it.name}
                                    .ToStorage();//将数据进行分组 
                        int a = x.AsInsertable.ExecuteCommand(); //执行插入
                        int b = x.AsUpdateable.ExecuteCommand(); //执行更新　
                    }
                    导入结果.导入结果 = result;
                    导入结果.仓库编号 = item.Key;
                    导入结果.DTOBOMDetailList = item.ToList();
                    导入结果.更新已领数量结果 = r > 0 ? "更新已领数量成功" : "更新已领数量失败";
                    导入结果List.Add(导入结果);
                }
            }

            return 导入结果List;
        }

        public static List<DTOU8材料出库单导入结果> 按批号生成U8材料出库单(long paigongId, string beiLiaoName, List<DTOBOMDetail> dTOBeiLiaoList实际用量)
        {
            List<DTOU8材料出库单导入结果> 导入结果List = new List<DTOU8材料出库单导入结果>();
            string 需要出库的仓库 = ConfigurationManager.AppSettings["cWhCode"].ToString();
            string[] 仓库 = 需要出库的仓库.Split(',');
            //查询派工记录的订单信息
            Z_派工 z_派工 = SqlSugarHelp.scope.Queryable<Z_派工>().Where(it => it.id == paigongId).IgnoreColumns(it => it.工票二维码).First();


            //查询订单子件，且不在半成品仓
            List<DTOBOMDetail> dTOBOMDetailList = dTOBeiLiaoList实际用量;
            Logger.Warn("备料接口，查询子件的数量" + dTOBOMDetailList.Count);

            if (dTOBOMDetailList != null && dTOBOMDetailList.Count > 0)
            {
                //根据仓库分组，因为材料出库单表头有材料仓库必填项
                var dtoBOMDetailGroup = dTOBOMDetailList.GroupBy(it => it.仓库编号);
                foreach (var item in dtoBOMDetailGroup)
                {
                    DTOU8材料出库单导入结果 导入结果 = new DTOU8材料出库单导入结果();
                    string 出库单号 = Get出库单号(DateTime.Today.ToString("yyyy-MM-dd"));
                    string result = U8出库单Port(出库单号, z_派工.订单号, z_派工.id.ToString(), item.Key, item.ToList(), z_派工.派工数量.GetValueOrDefault(), beiLiaoName, z_派工.cUser_Name);
                    int r = 0;
                    // 查出材料出库单号
                    rdrecord11 rdrecord11 = SqlSugarHelp.scope.Queryable<rdrecord11>().Where(it => it.cCode == 出库单号).First();
                    if (rdrecord11 != null)
                    {
                        r = 更新材料已领数量(item.ToList(), z_派工.订单号, z_派工.订单行号.ToString(), 0, 出库单号, rdrecord11, z_派工.产品编号);
                        //写入备料备注
                        List<Z_BeiLiaoMemo> Z_BeiLiaoMemoList = new List<Z_BeiLiaoMemo>();
                        foreach (var beiliao in item.ToList())
                        {
                            Z_BeiLiaoMemo memo = new Z_BeiLiaoMemo();
                            memo.备料出库结果 = result;
                            memo.订单行号 = beiliao.生产订单行号;
                            memo.子件行号 = beiliao.子件行号;
                            memo.派工单号 = paigongId;
                            Z_BeiLiaoMemoList.Add(memo);

                        }
                        var x = SqlSugarHelp.scope.Storageable(Z_BeiLiaoMemoList)
                                    .WhereColumns(it => new { it.派工单号, it.子件行号, it.订单行号 })//当然支持多个 new {it.id,it.name}
                                    .ToStorage();//将数据进行分组 
                        int a = x.AsInsertable.ExecuteCommand(); //执行插入
                        int b = x.AsUpdateable.ExecuteCommand(); //执行更新　
                    }
                    导入结果.导入结果 = result;
                    导入结果.仓库编号 = item.Key;
                    导入结果.DTOBOMDetailList = item.ToList();
                    导入结果.更新已领数量结果 = r > 0 ? "更新已领数量成功" : "更新已领数量失败";
                    导入结果List.Add(导入结果);
                }
            }

            return 导入结果List;
        }

        //public static List<DTOU8材料出库单导入结果> 生成U8材料出库单(long paigongId, string beiLiaoName, DTOBeiLiao dtoBeiLiao)
        //{
        //    List<DTOU8材料出库单导入结果> 导入结果List = new List<DTOU8材料出库单导入结果>();
        //    string 需要出库的仓库 = ConfigurationManager.AppSettings["cWhCode"].ToString();
        //    string[] 仓库 = 需要出库的仓库.Split(',');
        //    //查询派工记录的订单信息
        //    Z_派工 z_派工 = SqlSugarHelp.scope.Queryable<Z_派工>().Where(it => it.id == paigongId).First();


        //    //查询订单子件，且不在半成品仓
        //    List<DTOBOMDetail> dTOBOMDetailList = SqlSugarHelp.scope.Queryable<mom_order, mom_orderdetail, mom_moallocate, Inventory>((morder, orderdetail, moallocate, inv) => new JoinQueryInfos(
        //                                                                     JoinType.Left, morder.MoId == orderdetail.MoId,
        //                                                                     JoinType.Left, orderdetail.MoDId == moallocate.MoDId,
        //                                                                     JoinType.Left, inv.cInvCode == moallocate.InvCode
        //                                                                     )).Where((morder, orderdetail, moallocate, inv) =>
        //                                                                     !仓库.Contains(moallocate.WhCode) && morder.MoCode == z_派工.订单号 && orderdetail.SortSeq == z_派工.订单行号)
        //                                                                     .Select((morder, orderdetail, moallocate, inv) =>
        //                                                                     new DTOBOMDetail
        //                                                                     {
        //                                                                         生产订单ID = morder.MoId,
        //                                                                         生产订单号 = morder.MoCode,
        //                                                                         生产订单行ID = orderdetail.MoDId,
        //                                                                         生产订单行号 = orderdetail.SortSeq,
        //                                                                         产品编号 = orderdetail.InvCode,
        //                                                                         生产令单的所有子件用料资料ID = moallocate.AllocateId,
        //                                                                         子件物料编号 = moallocate.InvCode,
        //                                                                         子件物料名称 = inv.cInvName,
        //                                                                         工序行号 = moallocate.OpSeq,
        //                                                                         基本用量分子 = moallocate.BaseQtyN,
        //                                                                         基本用量分母 = moallocate.BaseQtyD,
        //                                                                         仓库编号 = moallocate.WhCode
        //                                                                     })
        //                                                                     .ToList();
        //    Logger.Warn("备料接口，查询子件的数量" + dTOBOMDetailList.Count);

        //    if (dTOBOMDetailList != null && dTOBOMDetailList.Count > 0)
        //    {
        //        //根据仓库分组，因为材料出库单表头有材料仓库必填项
        //        var dtoBOMDetailGroup = dTOBOMDetailList.GroupBy(it => it.仓库编号);
        //        foreach (var item in dtoBOMDetailGroup)
        //        {
        //            DTOU8材料出库单导入结果 导入结果 = new DTOU8材料出库单导入结果();
        //            string 出库单号 = Get出库单号(DateTime.Today.ToString("yyyy-MM-dd"));
        //            string result = U8出库单Port(出库单号, z_派工.订单号, z_派工.id.ToString(), item.Key, item.ToList(), z_派工.派工数量.GetValueOrDefault(), beiLiaoName);
        //            int r = 0;
        //            // 查出材料出库单号
        //            rdrecord11 rdrecord11 = SqlSugarHelp.scope.Queryable<rdrecord11>().Where(it => it.cCode == 出库单号).First();
        //            if (rdrecord11 != null)
        //            {
        //                r = 更新材料已领数量(item.ToList(), z_派工.订单号, z_派工.订单行号.ToString(), 0, 出库单号, rdrecord11, z_派工.产品编号);
        //            }
        //            导入结果.导入结果 = result;
        //            导入结果.仓库编号 = item.Key;
        //            导入结果.DTOBOMDetailList = item.ToList();
        //            导入结果.更新已领数量结果 = r > 0 ? "更新已领数量成功" : "更新已领数量失败";
        //            导入结果List.Add(导入结果);
        //        }
        //    }

        //    return 导入结果List;
        //}
        private static string U8出库单Port(string 出库单号, string 生产订单号, string 报工id, string cWhCode, List<DTOBOMDetail> dTOBOMDetailList, decimal 派工数量,string beiLiaoName,string 领料人)
        {
            string eaiUrl = ConfigurationManager.AppSettings["eaiUrl"].ToString();
            //拼接XML header
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load($"{System.AppDomain.CurrentDomain.BaseDirectory}/files/storeout.xml");
            //Logger.Warn("备料接口，导入U8XML" + xmlDoc.InnerXml);
            XmlElement root = xmlDoc.DocumentElement;
            //仓库编号
            XmlElement warehousecode = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/warehousecode");
            warehousecode.InnerText = cWhCode;
            //日期
            XmlElement date = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/date");
            date.InnerText = DateTime.Today.ToString("yyyy-MM-dd");
            //code
            XmlElement code = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/code");
            code.InnerText = 出库单号;
            //key = code.InnerText;
            //quantity
            XmlElement quantity1 = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/quantity");
            quantity1.InnerText = 派工数量.ToString();
            //ordercode
            XmlElement ordercode = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/ordercode");
            ordercode.InnerText = 生产订单号;
            //handler
            XmlElement handler = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/handler");
            handler.InnerText = beiLiaoName;
            //maker
            XmlElement maker = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/maker");
            maker.InnerText = beiLiaoName;
            //define1
            XmlElement define1 = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/define1");
            define1.InnerText = 报工id;
            //define2 领料人
            XmlElement define2 = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/header/define2");
            define2.InnerText = 领料人;
            //拼接XML body
            XmlElement body = (XmlElement)root.SelectSingleNode("/ufinterface/storeout/body");
            body.RemoveAll();
            for (int i = 0; i < dTOBOMDetailList.Count; i++)
            {
                XmlElement entry = xmlDoc.CreateElement("entry");
                body.AppendChild(entry);
                //< id >
                XmlElement id = xmlDoc.CreateElement("id");
                id.InnerText = (i + 1).ToString();
                entry.AppendChild(id);
                //< inventorycode > 
                XmlElement inventorycode = xmlDoc.CreateElement("inventorycode");
                inventorycode.InnerText = dTOBOMDetailList[i].子件物料编号;
                entry.AppendChild(inventorycode);
                // < quantity > 1
                XmlElement quantity = xmlDoc.CreateElement("quantity");
                quantity.InnerText = dTOBOMDetailList[i].应发数量.ToString();
                entry.AppendChild(quantity);

                XmlElement serial = xmlDoc.CreateElement("serial");
                serial.InnerText = dTOBOMDetailList[i].批次号;
                entry.AppendChild(serial);
            }
            xmlDoc.Save($"{System.AppDomain.CurrentDomain.BaseDirectory}/files/result.xml");
            //导入U8
            //HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(http://120.27.210.156/U8EAI/import.asp);///这是旭乐基的eai网址
            HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(eaiUrl);
            myRequest.Method = "POST";
            myRequest.ContentType = @"text/xml;charset=utf-8";
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            xmlDoc.Save(ms);
            byte[] bytes = ms.ToArray();
            myRequest.ContentLength = bytes.Length;
            System.IO.Stream s = myRequest.GetRequestStream();
            s.Write(bytes, 0, bytes.Length);
            s.Close();
            System.IO.StreamReader sr = new System.IO.StreamReader(myRequest.GetResponse().GetResponseStream());
            String retXml = sr.ReadToEnd();
            XmlDocument xmlDocResponse = new XmlDocument();
            xmlDocResponse.LoadXml(retXml);
            XmlElement ufinterface = xmlDocResponse.DocumentElement;
            string dsc = xmlDocResponse.SelectSingleNode("/ufinterface/item").Attributes["dsc"].Value;
            //dsc = xmlDocResponse.SelectSingleNode("/ufinterface/item/@dsc").Value;
            // MessageBox.Show(retXml);
            sr.Close();
            string path = $"{System.AppDomain.CurrentDomain.BaseDirectory}/files/材料出库单导入结果.txt";//文件存放路径，保证文件存在。
            StreamWriter sw = new StreamWriter(path, true);
            sw.WriteLine(retXml);
            sw.Close();
            return dsc;
        }

        private static string Get出库单号(string date)
        {
            string sql = @"select isnull(max(cCode),0) cCode from rdrecord11 where dDate = '" + date + "'";
            DataTable dt = SqlSugarHelp.scope.Ado.GetDataTable(sql);
            if (dt != null && dt.Rows.Count > 0 && !"0".Equals(dt.Rows[0]["cCode"].ToString()))
            {
                return (double.Parse(dt.Rows[0]["cCode"].ToString()) + 1).ToString();
            }
            else
            {
                return DateTime.Parse(date).ToString("yyyyMMdd") + "0001";
            }
        }

        private static int 更新材料已领数量(List<DTOBOMDetail> dTOBOMDetailList, string 生产订单号, string 生产订单行号, decimal 入库数量, string 材料出库单号, rdrecord11 rdrecord11, string 物料编号)
        {
          
            List<string> iMPoIdsLists = new List<string>();
            int result = 0;
            //更新材料出库单主表
            string sql = @"UPDATE rdrecord11 SET cBusCode = '" + 材料出库单号 + "' ,cPsPcode = '" + 物料编号
                            + "',cMPoCode = '" + 生产订单号 + "'WHERE ID ='" + rdrecord11.ID + "'";
            int a = SqlSugarHelp.scope.Ado.ExecuteCommand(sql);
            //更新材料出库单子表
            //查询订单子件信息

            if (dTOBOMDetailList.Count > 0)
            {
                for (int i = 0; i < dTOBOMDetailList.Count; i++)
                {
                   int r = SqlSugarHelp.scope.Updateable<rdrecords11>()
                                      .SetColumns(it => new rdrecords11 { cDefine22 = dTOBOMDetailList[i].生产令单的所有子件用料资料ID.ToString(),
                                                                                   cmocode = dTOBOMDetailList[i].生产订单号,
                                          invcode = dTOBOMDetailList[i].产品编号,
                                          imoseq = dTOBOMDetailList[i].生产订单行号,
                                          iopseq = dTOBOMDetailList[i].工序行号
                                      }).Where(it => it.ID == rdrecord11.ID && it.cInvCode == dTOBOMDetailList[i].子件物料编号).ExecuteCommand();
                    //更新子件已用量
                    if (r > 0)
                    {
                        result = updateMoallocate(dTOBOMDetailList[i].生产令单的所有子件用料资料ID);
                    }
                }
            }
            return result;
        }

        private static int updateMoallocate(int iMPoIdsLists)
        {
            int r = 0;
            string sql = @"update mom_moallocate set IssQty =(select SUM(iQuantity) 数量 from rdrecords11 where cDefine22 = '" + iMPoIdsLists + "' or iMPoIds = " + iMPoIdsLists + ") where AllocateId = '" + iMPoIdsLists + "'";
            r = SqlSugarHelp.scope.Ado.ExecuteCommand(sql);
            return r;
        }
    }
}